#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //img = new Image();
    img = nullptr;
    //主窗口
    setFixedSize(1450, 1200);
    setWindowTitle("bmpImage Processing");
    //菜单栏
    ui->menufile->setTitle("文件");
    ui->menuedit->setTitle("编辑");
    ui->menuimage->setTitle("图像");
    ui->menumode->setTitle("模式");
    ui->menucalculate->setTitle("计算");
    ui->menurevolve->setTitle("旋转");
    ui->menusharpening->setTitle("锐化");
    //工具栏
    ui->toolBar->addAction(ui->actionsave);
    ui->toolBar->addAction(ui->actionsave_as);
    ui->toolBar->addAction(ui->actionback);
    ui->toolBar->addAction(ui->actionnext);
    //ui->toolBar->addAction(ui->actioncrop);
    //ui->toolBar->addAction(ui->actioncut);
    ui->toolBar->setMovable(false);
    //显示区域
    ui->label->setGeometry(100, 75, 1200, 1000);
    //打开图片和图片显示区域
    connect(ui->actionopen, &QAction::triggered, this, &MainWindow::on_actionopen_triggered);
    //图片转为灰度图
    connect(ui->actiongray_scale, &QAction::triggered, this, &MainWindow::on_actiongray_scale_triggered);
    //图片锐化操作
    connect(ui->actionlaplacian, &QAction::triggered, this, &MainWindow::on_actionlaplacian_triggered);//laplacian锐化
    connect(ui->actionsobel, &QAction::triggered, this, &MainWindow::on_actionsobel_triggered);
    connect(ui->actionhigh_passFilter, &QAction::triggered, this, &MainWindow::on_actionhigh_passFilter_triggered);
    //图片保存和前进后退操作
    connect(ui->actionsave, &QAction::triggered, this, &MainWindow::on_save_triggered);
    connect(ui->actionsave_as, &QAction::triggered, this, &MainWindow::on_save_as_triggered);
    connect(ui->actionback, &QAction::triggered, this, &MainWindow::on_back_triggered);
    connect(ui->actionnext, &QAction::triggered, this, &MainWindow::on_next_triggered);
    //修改宽和高
    connect(ui->actionresize, &QAction::triggered, this, &MainWindow::on_actionresize_triggered);
    //计算
    connect(ui->actionaverage, &QAction::triggered, this, &MainWindow::on_actionaverage_triggered);
    connect(ui->actionvariance, &QAction::triggered, this, &MainWindow::on_actionvariance_triggered);
    //翻转
    connect(ui->actionup_and_down, &QAction::triggered, this, &MainWindow::on_actionfilpUpanDown_triggered);
    connect(ui->actionleft_and_right, &QAction::triggered, this, &MainWindow::on_actionfilpLeftAndRight_triggered);
    //高斯模糊
    connect(ui->actiongaussianblur, &QAction::triggered, this, &MainWindow::on_actiongaussianblur_triggered);
    //二值化
    connect(ui->actionbinarization, &QAction::triggered, this, &MainWindow::on_actionbinarization_triggered);
    //轮廓提取
    connect(ui->actioncontourdetection, &QAction::triggered, this, &MainWindow::on_actioncontourdetection_triggered);
    //关闭图片
    connect(ui->actionclose, &QAction::triggered, this, &MainWindow::on_close_triggered);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::showImg()
{
    //显示图片
    QImage * image = new QImage(img->getData(), img->getPrimaryWidth(), img->getHeight(), img->getWidth() * 3, QImage::Format_RGB888);
    ui->label->setPixmap(QPixmap::fromImage(*image));
    ui->label->setAlignment(Qt::AlignCenter);
    if(img->getHeight() > 1200 && img->getPrimaryWidth() > 1000)
        ui->label->setScaledContents(true);
    ui->label->show();
}

void MainWindow::on_actionopen_triggered()
{
    img = new Image();
    fileName = QFileDialog::getOpenFileName(this, tr("open a file."), "D:/", tr("images(*.bmp)"));
    if(fileName == "")
    {
        return;
    }
    const char * name = fileName.toStdString().c_str();
    img->ReadBMP(name);
    if(!copies.empty())
    {
        QVector<Image> t;
        copies.swap(t);
        index = 0;
        //qDebug() << copies.size();
    }
    copies.push_back(*img);

    showImg();
}

void MainWindow::on_actionlaplacian_triggered()
{
    checkCopies();
    img->LaplacainSharpening();
    copies.push_back(*img);
    index++;
    showImg();
}

void MainWindow::on_actionsobel_triggered()
{
    checkCopies();
    img->SobelSharpening();
    copies.push_back(*img);
    index++;
    showImg();
}

void MainWindow::on_actionhigh_passFilter_triggered()
{
    checkCopies();
    img->High_passFilter();
    copies.push_back(*img);
    index++;
    showImg();
}

void MainWindow::on_actiongray_scale_triggered()
{
    checkCopies();
    img->ToGray();
    copies.push_back(*img);
    index++;
    showImg();
}

void MainWindow::on_save_triggered()
{
    const char * name = fileName.toStdString().c_str();
    img->WriteBMP(name);
    QMessageBox::warning(this, tr("提示"), tr("保存文件成功"));
    QVector<Image> t;
    copies.swap(t);
    copies.push_back(*img);
    index = 0;
}

void MainWindow::on_save_as_triggered()
{
    //创建新文件，保持原有副本    
    QFileDialog fileDialog;
    QString name = fileDialog.getSaveFileName(this, tr("open a file"), "D:/", tr("images(*.bmp)"));
    if(name == "")
    {
        return;
    }
    const char * filename = name.toStdString().c_str();
    img->WriteBMP(filename);
    QMessageBox::warning(this, tr("提示"), tr("保存文件成功"));
}

void MainWindow::on_back_triggered()
{
    if(index>0)
    {
        delete img;
        img = new Image(copies[--index]);
        showImg();
    }
}

void MainWindow::on_next_triggered()
{
    if(index < copies.size() - 1)
    {
        delete img;
        img = new Image(copies[++index]);
        showImg();
    }
}

void MainWindow::checkCopies()
{
    if(index + 1 < copies.size() && index > 0)
    {
        QVector<Image> newCopies;
        QVector<Image>::iterator it;
        for(it = copies.begin(); it!= copies.begin() + index; it++)
        {
            newCopies.push_back(*it);
        }
        QVector<Image> t;
        copies.swap(t);
        //qDebug() << newCopies.size();
        copies = newCopies;
        delete img;
        img = new Image(copies[index - 1]);
    }
    else if(index + 1 < copies.size() && index == 0)
    {
        QVector<Image> newCopies;
        newCopies.push_back(copies[0]);
        QVector<Image> t;
        copies.swap(t);
        copies = newCopies;
        delete img;
        img = new Image(copies[index]);
    }
}

void MainWindow::on_actionfilpUpanDown_triggered()
{
    checkCopies();
    img->FilpUpAndDown();
    copies.push_back(*img);
    index++;
    showImg();
}

void MainWindow::on_actionfilpLeftAndRight_triggered()
{
    checkCopies();
    img->FilpLeftAndRight();
    copies.push_back(*img);
    index++;
    showImg();
}

void MainWindow::on_close_triggered()
{
    if(img != nullptr)
    {
        ui->label->clear();
        delete img;
        img = nullptr;
        QVector<Image> t;
        copies.swap(t);
        fileName = "";
        index = 0;
    }
    else
    {
        QMessageBox::warning(this, tr("提示"), tr("当前未打开文件"));
        return;
    }

}

void MainWindow::on_actionresize_triggered()
{
    checkCopies();
    QDialog dialog(this);
    QFormLayout form(&dialog);
    form.addRow(new QLabel("User input:"));
    // Value1
    QString value1 = QString("Height: ");
    QSpinBox *spinbox1 = new QSpinBox(&dialog);
    spinbox1->setRange(100, 10000);
    form.addRow(value1, spinbox1);
    // Value2
    QString value2 = QString("Width: ");
    QSpinBox *spinbox2 = new QSpinBox(&dialog);
    spinbox2->setRange(100, 10000);
    form.addRow(value2, spinbox2);
    // Add Cancel and OK button
    QDialogButtonBox buttonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
        Qt::Horizontal, &dialog);
    form.addRow(&buttonBox);
    connect(&buttonBox, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
    connect(&buttonBox, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
    // Process when OK button is clicked
    if (dialog.exec() == QDialog::Accepted)
    {
        if(spinbox1->value() <= 0 || spinbox2->value() <= 0)
            return;
        img->resize(spinbox1->value(), spinbox2->value());
        copies.push_back(*img);
        index++;
        showImg();
    }
}

void MainWindow::on_actionaverage_triggered()
{
    double * averages = img->average();
    QString displayInfo = tr("均值计算结果:\r\n\r\n");
    QString tempInfo;
    tempInfo = tr("R: %1\r\n").arg(averages[0]);
    displayInfo += tempInfo;
    tempInfo = tr("G: %1\r\n").arg(averages[1]);
    displayInfo += tempInfo;
    tempInfo = tr("B: %1\r\n").arg(averages[2]);
    displayInfo += tempInfo;
    QMessageBox::information(this, tr("result"), displayInfo);
}

void MainWindow::on_actionvariance_triggered()
{
    double * variances = img->variance();
    QString displayInfo = tr("方差计算结果:\r\n\r\n");
    QString tempInfo;
    tempInfo = tr("R: %1\r\n").arg(variances[0]);
    displayInfo += tempInfo;
    tempInfo = tr("G: %1\r\n").arg(variances[1]);
    displayInfo += tempInfo;
    tempInfo = tr("B: %1\r\n").arg(variances[2]);
    displayInfo += tempInfo;
    QMessageBox::information(this, tr("result"), displayInfo);
}

void MainWindow::on_actiongaussianblur_triggered()
{
    checkCopies();
    bool bRet = false;
    double sigma = QInputDialog::getDouble(this, tr("选择标准差"), tr("请输入σ"),
                                           0.0, 0.0, 100.0, 1, &bRet);
    if (!bRet)
    {
        return;
    }
    img->Gaussian_Blur(sigma);
    copies.push_back(*img);
    index++;
    showImg();
}

void MainWindow::on_actionbinarization_triggered()
{
    checkCopies();
    img->Binarization();
    copies.push_back(*img);
    index++;
    showImg();
}

void MainWindow::on_actioncontourdetection_triggered()
{
    checkCopies();
    img->Contour_Detection();
    copies.push_back(*img);
    index++;
    showImg();
}
